package com.alan.service.impl;

import com.alan.domain.ResponseResult;
import com.alan.domain.entity.LoginUser;
import com.alan.domain.entity.User;
import com.alan.domain.vo.BlogUserLoginVo;
import com.alan.domain.vo.UserInfoVo;
import com.alan.service.BlogLoginService;
import com.alan.utils.BeanCopyUtils;
import com.alan.utils.JwtUtil;
import com.alan.utils.RedisCache;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;

@Service
public class BlogLoginServiceImpl implements BlogLoginService {

    @Resource
    private AuthenticationManager authenticationManager;//认证管理器

    @Resource
    private RedisCache redisCache;//Redis工具类


    @Override
    public ResponseResult login(User user) {
        //利用authenticationManager进行认证
        //首先封装一个认证信息令牌（token）
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken
                        (user.getUserName(),user.getPassword());
        //然后通过authenticationManager进行认证
        //注意：authenticationManager默认调用自带的UserDetailService
        //而默认的UserDetailService默认是从内存中进行查询数据
        //所以我们需要重新创建UserDetailService,实现查询数据库数据
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        //判断是否认证通过
        if (Objects.isNull(authenticate)){
            //TODO: 统一异常处理
            throw new RuntimeException("Authentication failed");
        }

        //if认证成功，获取UserId，生成Token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        Long userId = loginUser.getUser().getId();
        String token = JwtUtil.createJWT(userId.toString());

        //将用户完整信息存入Redis
        //TODO: loginUser封装权限信息
        redisCache.setCacheObject("bloglogin"+userId,loginUser);

        //最后，把token和UserInfo封装 返回
//        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        //上面的user指的是前端传来的user，内部只有username和password
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(loginUser.getUser(), UserInfoVo.class);
        BlogUserLoginVo vo = new BlogUserLoginVo(token,userInfoVo);

        return ResponseResult.okResult(vo);
    }

    @Override
    public ResponseResult logout() {
        //删除Redis的用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long id = loginUser.getUser().getId();
        String key = "bloglogin"+id;
        redisCache.deleteObject(key);
        return ResponseResult.okResult();
    }
}
